/**
  ETFAna project, Anyang Normal University && IMP-CAS
  \class ETFDCTaU
  \brief the DCs with smaller drift cells (5mm), designed for tracking upstraem TA
  by P.Ma
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2023-04-16
  \date 2023-04-16 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date         <th>Author      <th>Description                   </tr>
  <tr>  <td>2023-04-16   <td>Asia Sun    <td>file created                  </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#include <cmath>
#include "ETFDCTaU.h"
#include "ETFMsg.h"
#include "ETFParaManager.h"
#include "ETFYaml.h"
#include "ETFMath.h"

ETFDCTaU::ETFDCTaU(const char *name) : ETFDCTa(name){
  // configure the DC //
  fNL = 16;
  fSenseWireDistance = 5.; fMaxDL = fSenseWireDistance/2.;
  fLayerSpace12 = -5.; fLayerSpaceXY = -12.5; fStagger12 = 2.5;
  fX0Min = -40.; // fSenseWireDistance*(fNL/2)

  fStaggerY12 = -2.5; fY0Min = -35.;

  // pass user trig bound and drift time bound parameters //
  const ETFYaml &trigBConfig = (*fpm->GetMisPara())["dcTaUTrigB"];
  if(trigBConfig){
    fTrigLB = trigBConfig[0].as<double>();
    fTrigHB = trigBConfig[1].as<double>();
  } // end if
  // pass user trig bound and drift time bound parameters //
  const ETFYaml &DTBConfig = (*fpm->GetMisPara())["dcTaUDTB"];
  if(DTBConfig){
    fDTLB = DTBConfig[0].as<double>();
    fDTHB = DTBConfig[1].as<double>();
  } // end if

  // fill channel id map //
  for(const auto &chid : fChIdConfig){
    FillChIdMap(chid.as<int>());
    type[0]++;
  } // end for over cables
} // end ctor

ETFDCTaU::~ETFDCTaU(){}

// fill the channel map for X or Y wires
// XY, X1-X2, senseWireId
void ETFDCTaU::FillChIdMap(int chId0){
  if(chId0 < 0) return;
  for(int i = 0; i < 32; i++){
    int wireId = i%16;
    if(0 == type[0]) wireId = 15 - wireId; // X wire: reverse order: 0->15 : 15->0
    //        chanel id      X-Y     X1-2  wireId
    SetChMap(chId0+i, uid(type[0], i/16, wireId));
  } // end if
} // end member function FillCableChMap

// r = r(t); drift distance - drift time relation
double ETFDCTaU::SpaceTimeRelation(double t){
  // usually STR at different HVs are so different as worth special treatment
  // be it a garfield simulation, or user-refined tuning based on experiment data analysis
  static const double T0 = fDTHB*0.4; // the fitted rt relation is invalid for t > T0
  const double T1 = fDTHB*0.7;
  const int POLN = fvstr.size();
  double r = 0.;

  if(!POLN) r = ETFVDC::SpaceTimeRelation(t); // a parabola-form STR
  else{
    if(t < T0) for(int i = POLN; i--;) r += fvstr[i]*pow(t, i);
    else if(t <= T1){ // we use a linear smoothing here with (T0, r0) -> (T1, fMaxDL)
      double r0 = 0.;
      for(int i = POLN; i--;) r0 += fvstr[i]*pow(T0, i);
      r = (fMaxDL - r0) / (T1 - T0) * (t - T1) + fMaxDL;
    } // end inner else
    else r = fMaxDL;
  } // end else
  if(r < 0. || t <= fDTLB) r = 0.;
  if(r > fMaxDL || t > fDTHB) r = fMaxDL;

  return r;
} // end member function SpaceTimeRelation
